package turtle.system.doug.turtleaction;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TreeMap;

import turtle.system.pt.BarSet;
import turtle.system.pt.DailyExec;
import arbor.mining.util.stock.OHLC;
import arbor.mining.util.stock.StockEntity;

public class TurtleActEvaluator {
  public static final boolean supportAddAction = false;
  public static final String START_TIME = "1999/01/05";
  //public static final String START_TIME = "2008/01/02";
  public static final String END_TIME = "2009/06/10";

  public static final String historyFN = "tmp/history_profit.csv";
  TreeMap<Calendar, ArrayList<TurtleAction>> actMap = new TreeMap<Calendar, ArrayList<TurtleAction>>();
  TreeMap<Calendar, ArrayList<TurtleAddAction>> addMap = new TreeMap<Calendar, ArrayList<TurtleAddAction>>();
  TreeMap<String, Double> dayProfitMap = new TreeMap<String, Double>();
  TreeMap<String, StockEntity> allStockPrices = DailyExec
			.getAllStockData(DailyExec.WTX1_PREFIX_FN + DailyExec.FN_SUFFIX);
  
  private static final DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
  public TurtleActEvaluator(ArrayList<TurtleAction> actList, ArrayList<TurtleAddAction> addList) {
	  for (int i=0;i<actList.size();i++) {
		  if (!actMap.containsKey(actList.get(i).tomorrowBar2.today)) {
			  ArrayList<TurtleAction> r = new ArrayList<TurtleAction>();
			  r.add(actList.get(i));            
			  actMap.put(actList.get(i).tomorrowBar2.today,  r);
		  }
		  else {
			  actMap.get(actList.get(i).tomorrowBar2.today).add(actList.get(i));
		  }
	  }	  

	  if (supportAddAction) {
	    for (int i=0;i<addList.size();i++) {
	      TurtleAddAction addAct = addList.get(i);
	      TurtleAction fakeIn = new TurtleAction(addAct.todayBar2,addAct.tomorrowBar2);
	      TurtleAction fakeOut = new TurtleAction(addAct.todayBar2,addAct.tomorrowBar2);
	      /*這行有錯*/
	      fakeIn.setData(TurtleAction.IN_ACTION, addAct.addLongOrShort, -1, addAct.addInTime, 0);
	      
		  if (!addMap.containsKey(addAct.todayBar2.today)) {
			  ArrayList<TurtleAddAction> r = new ArrayList<TurtleAddAction>();
			  r.add(addList.get(i));
			  addMap.put(addList.get(i).todayBar2.today,  r);
		  }
		  else {
			  addMap.get(addList.get(i).todayBar2.today).add(addList.get(i));
		  }
	      
	      
	      /*先不考慮停損!*/
	      fakeOut.setData(TurtleAction.OUT_ACTION, addAct.addLongOrShort, -1, addAct.addOutTime, 0);
	      
	    }	  
	  }
  }
	

    public int getLotByProfit(double curProfit) {
    	int lot = ((int)curProfit/3000);
    	if (lot<1)
    		lot = 1;
    	if (lot > 30)
    		lot = 30;
    	return lot;
    }
	public int getLot(GregorianCalendar start, String date) {
		GregorianCalendar cur = new GregorianCalendar();
		GregorianCalendar comp = (GregorianCalendar) start.clone();
		int lot = 1;
		try {
			cur.setTime(df.parse(date));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		comp.add(Calendar.YEAR, 1);
		while (cur.after(comp)) {
			comp.add(Calendar.YEAR, 1);
			lot = lot * 2;
		}
		if (lot > 32)
			lot = 32;
		lot = 1;
		return lot;
	}
	public void exec() {
		GregorianCalendar start = new GregorianCalendar();
		GregorianCalendar end = new GregorianCalendar();
		GregorianCalendar iterTime = new GregorianCalendar();
		BufferedWriter writer =null;
		try {
		    writer = new BufferedWriter(new FileWriter(historyFN));
		}catch (IOException e) {
			System.out.println(e);
		}
		
		int numInHand = 0; /* 正代表多單數，負代表空單數，0為沒單 */
		double currentProfit = 0;
		int currentLot = 1;
		
		try {
			start.setTime(df.parse(START_TIME));
			end.setTime(df.parse(END_TIME));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		iterTime.setTime(start.getTime());
		String iterString = df.format(iterTime.getTime());
		double prevClosePrice = allStockPrices.get(iterString).ohlc.close;
		double prevADX = allStockPrices.get(iterString).adx;
		
		while (!iterTime.after(end)) {
			iterString = df.format(iterTime.getTime());
			currentLot = getLot(start, iterString);
			//currentLot = getLotByProfit(currentProfit);
			if (!allStockPrices.containsKey(iterString)) {
				iterTime.add(Calendar.DATE, 1);
				continue; /* 沒開市 */
			}
			else {
				OHLC today = allStockPrices.get(iterString).ohlc;				
								
				if (!actMap.containsKey(iterTime)) {
					/*今天沒動作*/
					currentProfit += (numInHand)* (today.close - prevClosePrice);
				}
				else {
					/*開盤結算一下*/
					currentProfit += (numInHand)* (today.open - prevClosePrice);
					
					ArrayList<TurtleAction> actList = actMap.get(iterTime);					
					int handleTrade = 0;
					/*計算開盤動作*/
					for (int i=0;i<actList.size();i++) {
					  TurtleAction act = actList.get(i);
					  //System.out.println("");
					  //act.getActionMessage();
					  if (act.inOrOut == TurtleAction.IN_ACTION && 
						  act.longOrShort == TurtleAction.LONG_ACTION) {
						  /*一律開盤進場*/						  
						  numInHand+=currentLot;
						  handleTrade++;
					  }
					  else if (act.inOrOut == TurtleAction.OUT_ACTION && 
							  act.longOrShort == TurtleAction.LONG_ACTION &&
							  act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_START) {
						  /*開盤出場*/						  
						  numInHand-=currentLot;
						  handleTrade++;
					  }
					  else if (act.inOrOut == TurtleAction.IN_ACTION && 
							  act.longOrShort == TurtleAction.SHORT_ACTION) {
						  /*開盤進場*/						  
						  numInHand-=currentLot;
						  handleTrade++;
					  }
					  else if (act.inOrOut == TurtleAction.OUT_ACTION && 
							  act.longOrShort == TurtleAction.SHORT_ACTION &&
							  act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_START) {
						  /*開盤出場*/						  
						  numInHand+=currentLot;
						  handleTrade++;
					  }
					  else if (act.inOrOut == TurtleAction.IN_ACTION && 
					      act.longOrShort == TurtleAction.LONG_ACTION_KEEP_PREV_TRADE_OR_ADVANCED_IN) {
						  currentProfit += (currentLot)* (today.open - prevClosePrice);
						  numInHand+=currentLot; /*收盤進場*/						  
						  handleTrade++;
					  }
					  else if (act.inOrOut == TurtleAction.IN_ACTION && 
					      act.longOrShort == TurtleAction.SHORT_ACTION_KEEP_PREV_TRADE_OR_ADVANCED_IN) {
						  currentProfit += (currentLot)* (prevClosePrice-today.open);
						  numInHand-=currentLot; /*收盤進場*/
						  handleTrade++;
					  } 			  
					}
					
					/*先假設每一單都撐到最後*/
					currentProfit += (numInHand)* (today.close - today.open);
					
					/*計算盤中動作*/
					for (int i=0;i<actList.size();i++) {
						  TurtleAction act = actList.get(i);
						  if (act.inOrOut == TurtleAction.OUT_ACTION &&
						      act.longOrShort == TurtleAction.LONG_ACTION &&
							  act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_INSTANT) {							  						  
							  numInHand-=currentLot;
							  currentProfit -= currentLot*(today.close - act.price); /*沒撐到最後*/
							  handleTrade++;
						  }
						  else if (act.inOrOut == TurtleAction.OUT_ACTION &&
							      act.longOrShort == TurtleAction.SHORT_ACTION &&
								  act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_INSTANT) {							  						  
								  numInHand+=currentLot;
								  currentProfit -= currentLot*(act.price - today.close); /*沒撐到最後*/
								  handleTrade++;
					      } 
					}
							  
					  /*收盤結算一下*/
					for (int i=0;i<actList.size();i++) {
					  TurtleAction act = actList.get(i);
					  if (act.inOrOut == TurtleAction.OUT_ACTION && 
						      act.longOrShort == TurtleAction.LONG_ACTION &&
						      act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_END) {
							  /*收盤出場*/						  
							  numInHand-=currentLot;
							  handleTrade++;
				      }
					  else if (act.inOrOut == TurtleAction.OUT_ACTION && 
					      act.longOrShort == TurtleAction.SHORT_ACTION &&
					      act.outAtStartOrEnd == TurtleAction.OUT_ACTION_AT_END) {
						  /*收盤出場*/						  
						  numInHand+=currentLot;
						  handleTrade++;
					  }					  
					}
				}
				prevClosePrice = today.close;
				prevADX = allStockPrices.get(iterString).adx;
				iterTime.add(Calendar.DATE, 1);				
			}

			dayProfitMap.put(iterString, new Double(currentProfit));
			try {
				writer.write(iterString+","+prevClosePrice+","+numInHand+","+(int)currentProfit+","+prevADX+"\n");
			}catch (IOException e) {
				System.out.println(e);
			}			
		}
		try {
			writer.close();
		}catch (IOException e) {
			System.out.println(e);
		}
		
		ProfitAnalyzer analyzer = new ProfitAnalyzer(dayProfitMap);
		try {
			analyzer.analyzeBaseStatistic();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
  
}
